// 牛牛的背包问题 & 世界冰球锦标赛
// 牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。
// 牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。
// 牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。
// 输入描述：
// 输入包括两行
// 第一行为两个正整数n和w(1 <= n <= 30, 1 <= w <= 2 * 10^9),表示零食的数量和背包的容量
// 第二行n个正整数v[i](0 <= v[i] <= 10^9),表示每袋零食的体积
// 输出描述：
// 输出一个正整数, 表示牛牛一共有多少种零食放法。
// 测试链接 : https://www.nowcoder.com/practice/d94bb2fa461d42bcb4c0f2b94f5d4281
// 测试链接 : https://www.luogu.com.cn/problem/P4799
// 提交以下所有代码，可以直接通过

#include <iostream>
#include <algorithm>

using namespace std;

const int MAXN = 40;
// 总共最多 40 个数，左侧最多 20 个数
// 每个数选或不选，共 2 ^ 20 个累加和
const int MAXM = 1 << 20;
// 注意要使用 long，否则数据会溢出
long arr[MAXN];
long lsum[MAXM];
long rsum[MAXM];
// 题目的输入参数
long n, w; 

// arr[i...e]结束，e 再往右就不展开了
// s 是累加和
// 返回值：ans 数组填到了什么位置
// j 是小于等于 w 的累加和的方案数
int f(int i, int e, long s, long* ans, int j)
{
    if(s > w) return j; // 超出限制了，直接返回 j
    if(i == e)
    {
        ans[j++] = s;
    }
    else
    {
        // 不要 arr[i]
        j = f(i + 1, e, s, ans, j);
        // 要 arr[i]
        j = f(i + 1, e, s + arr[i], ans, j);
    }
    return j;
}

long compute()
{
    // 手玩的一个例子 n : 6   w : 7  {1, 2, 3, 2, 3, 2}  
    int lsize = f(0, n >> 1, 0, lsum, 0);
    int rsize = f(n >> 1, n, 0, rsum, 0);
    long ans = 0;
    // 排序 + 双指针
    sort(lsum, lsum + lsize);
    sort(rsum, rsum + rsize);
    // lsum {0, 1, 2, 3, 3, 4, 5, 6}
    // rsum {0, 2, 2, 3, 4, 5, 5, 7}
    for(int i = lsize - 1, j = 0; i >= 0; --i)
    {
        while(j < rsize && lsum[i] + rsum[j] <= w) ++j;
        ans += j;
    }
    return ans;
}

int main()
{
    cin >> n >> w;
    for(int i = 0; i < n; ++i) cin >> arr[i];
    cout << compute() << endl;
    
    return 0;
}

/*
// 使用 vector 的代码，感觉有点小慢

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int MAXN = 40;
const int MAXM = 1 << 20;
vector<long> arr(MAXN);
vector<long> lsum(MAXM);
vector<long> rsum(MAXM);
long n, w;

// arr[i...e]结束，e再往右就不展开了
// s是累加和
// 返回值：ans数组填到了什么位置
int f(int i, int e, long s, vector<long>& ans, int j)
{
    if(s > w) return j;
    if(i == e)
    {
        ans[j++] = s;
    }
    else
    {
        // 不要arr[i];
        j = f(i + 1, e, s, ans, j);
        // 要arr[i]
        j = f(i + 1, e, s + arr[i], ans, j);
    }
    return j;
}

long compute()
{
    int lsize = f(0, n >> 1, 0, lsum, 0);
    int rsize = f(n >> 1, n, 0, rsum, 0);
    sort(lsum.begin(), lsum.begin() + lsize);
    sort(rsum.begin(), rsum.begin() + rsize);
    
    long ans = 0;
    for(int i = lsize - 1, j = 0; i >= 0; --i)
    {
        while(j < rsize && lsum[i] + rsum[j] <= w) ++j;
        ans += j;
    }
    return ans;
}

int main()
{
    cin >> n >> w;
    for(int i = 0; i < n; ++i) cin >> arr[i];
    cout << compute() << endl;
    
    return 0;
}

*/ 